package cluedo.gui;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyledDocument;

import cluedo.Player;
import cluedo.Zombie;
import  static cluedo.Player.log;


/**
 * Questa classe rappresenta l'area in cui sono visualizzati i nicknames dei giocatori durante una partita
 *
 */
public class NicknamesArea extends JTextPane {


	private static final long serialVersionUID = -9038764884718692931L;

	/**
	 * Mappatura tra nickname del player e relativa riga nell'area dei Nickname
	 */
	private HashMap<String,NickRow> lines=new HashMap<String,NickRow>();
	
	/**
	 * Nickname del proprietario del gruppo
	 */
	private String currentGroupOwner=null;
	
	/**
	 * il giocatore associato alla MainWindow in cui e' contenuta la NicknameArea
	 */
	private Player myPlayer;
	
	/**
	 * Nickname di chi ha il turno
	 */
	private String currentTurnPlayer=null;
	
	
	public NicknamesArea(Player myPlayer){
		super();
		this.myPlayer=myPlayer;
	}
	
	
	/**
	 * Aggiunge un nickname alla NicknamesArea segnalando graficamente se 
	 * e' il proprietario del gruppo e se e' il suo turno
	 * @param pl il giocatore il cui nickname deve essere aggiunto
	 */
	
	public void addNicknameLine(Zombie pl){
		
				NickRow tmp=null;  
				StyledDocument doc = this.getStyledDocument();
				SimpleAttributeSet nameStyle = new SimpleAttributeSet();
				
		        String playerName = pl.getNickname();
		        
		        log.printLog("NicknamesArea: aggiungo la riga di "+playerName);	

					
				tmp = new NickRow(myPlayer,this,pl);
				try{
					doc.insertString(doc.getLength(),"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
					
				lines.put(playerName,tmp);
				String ownerName=null;
				ownerName = myPlayer.getZombieGroupOwner(myPlayer.getMyPlayGroup()).getNickname();
					
				this.currentGroupOwner=ownerName;
					
		        if(playerName.equals(ownerName)){ //proprietario del gruppo
			        
		        	log.printLog("NicknamesArea: "+playerName+" e' il proprietario del gruppo. Rendo visibile l'icona proprietario");	
		        		
		        	tmp.setOwner(true);
		        		
		        }
		        	
		        if(playerName.equals(myPlayer.whoseTurnIsIt())){
		        	
		        	log.printLog("NicknamesArea: "+playerName+" ha il turno. Rendo visibile l'icona turno");	
		        	
		        	tmp.setHisTurn(true);
		        	this.currentTurnPlayer=playerName;
		        		
		       }	
		        
		       if(!pl.isAlive()){ //zombie morto
		    	   
		    	   log.printLog("NicknamesArea: "+playerName+" e' morto ancor prima di iniziare la partita. Rendo visibile l'icona M.Jackson");	

		    	   tmp.setZombie(true);
		       }
		
	}
	
	/**
	 * Mostra nella nicknames area un player come zombie
	 * @param pl il giocatore che e' diventato uno zombie
	 */
	
	public void zombieNicknameLine(Zombie pl){
	
		String name= pl.getNickname();	
		
		if(!lines.get(name).isZombieShown()){ //l'icona che indica che il player e' uno zombie non e' mostrata
		
			log.printLog("NicknamesArea: "+name+" e' morto. Rendo visibile l'icona M.Jackson associata");	

		lines.get(name).setZombie(true);
		
		}
		
		
	}
	
	/**
	 * Rimuove un nickname dalla NicknamesArea
	 * @param pl il giocatore da rimuovere
	 */
	/*
	 * Lasciare questo metodo in caso serva
	public void removeNicknameLine(PlayerIntf pl){
	
		String name=null;
		try {
			name= pl.getNickname();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		
		String currentText = this.getText();
		
		StyledDocument doc = this.getStyledDocument();
		
		
		// Cerca nel testo il nickname da rimuovere
		String regex = "\\b"+name+"\\b";
		
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(currentText);
		
		int nicknameIndexStart=-1;
		int nicknameIndexEnd=-1;
		
		if(matcher.find() == true){
		          nicknameIndexStart = matcher.start();		
		          nicknameIndexEnd = matcher.end();	
		}
		
		
		// alternativa 1) Traccia la linea sul nome eliminato e il nome diventa appena visibile nell'interfaccia
		//lines.get(name).setOwner(false);
		//lines.get(name).setHisTurn(false);
		//MutableAttributeSet attr = new SimpleAttributeSet();
		//StyleConstants.setStrikeThrough(attr , true);
		//StyleConstants.setForeground(attr , Color.DARK_GRAY);
		//doc.setCharacterAttributes(nicknameIndexStart, nicknameIndexEnd, attr, false);
	
			
			
		 
		//alternativa 2) In alternativa al tracciamento della linea, il nickname puo' essere cancellato dall'area  
				
		int baseLength = lines.get(name).getBaseLength();
		
		
		int startIndex = nicknameIndexStart - baseLength;
		
		
		int lineLength=nicknameIndexEnd-startIndex+1;

			
		try {
			doc.remove(startIndex,lineLength);
		} catch (BadLocationException e) {
			System.err.println("NicknamesArea: Errore nella rimozione del nickname");
			e.printStackTrace();
		}
		
		// Fine seconda alternativa 
		
					
		lines.remove(name);
		
		if(currentGroupOwner.equals(name)){
	        
            currentGroupOwner=null;
                    
            }
		
		if(currentTurnPlayer.equals(name)){
			
			currentTurnPlayer=null;
			
		}

				
	}*/
	
	
	/**
	 * Porta la nicknames area nella posizione della riga del player
	 * @param nickname il nickname del player
	 */
	public void scrollToPosition(String name){
		
		// Cerca nel testo il nickname da rimuovere
		String regex = "\\b"+name+"\\b";
		
		String currentText = this.getText();
		
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(currentText);
				
		int nicknameIndexStart=-1;
				
		if(matcher.find() == true){
				     nicknameIndexStart = matcher.start();		
				     
				     int baseLength = lines.get(name).getBaseLength();
						
				     int startIndex = nicknameIndexStart - baseLength;
				    
				     this.setCaretPosition(startIndex);
				}
		
		
	}
	
	/**
	 * Imposta e visualizza, nella NicknameArea, il proprietario del gruppo
	 * @param pl il player proprietario del gruppo
	 */
	public void updateGroupOwner(Zombie pl){
		
		String name= pl.getNickname();
		
		if(currentGroupOwner!=null)
			lines.get(currentGroupOwner).setOwner(false);
		log.printLog("NicknamesArea: "+name+" e' il nuovo proprietario. Rendo visibile l'icona proprietario associata");	
		lines.get(name).setOwner(true);
		currentGroupOwner=name;
		this.scrollToPosition(name);
		
	}
	
	/**
	 * Imposta e visualizza, nella NicknameArea, a chi spetta il turno 
	 * @param pl il player a cui spetta il turno
	 */
	public void updatePlayerTurn(Zombie pl){
		
		String name= pl.getNickname();

		
		if(currentTurnPlayer!=null)
			lines.get(currentTurnPlayer).setHisTurn(false);
		log.printLog("NicknamesArea: "+name+" ha adesso il turno. Rendo visibile l'icona turno associata");	
		lines.get(name).setHisTurn(true);
		currentTurnPlayer=name;
		this.scrollToPosition(name);
		
	}
	
	
	
}
